/* 
 * Copyright (C) 2012 UTSChedule
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package utsc.apps.utschedule.ui.activities.adapters;

import java.util.ArrayList;
import java.util.List;

import utsc.apps.utschedule.R;
import utsc.apps.utschedule.classes.Assignment;
import utsc.apps.utschedule.classes.Course;
import utsc.apps.utschedule.classes.Exam;
import utsc.apps.utschedule.classes.GenericTask;
import utsc.apps.utschedule.classes.UofTGrade;
import utsc.apps.utschedule.util.database.DatabaseManager;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

/**
 * The list adapter for Calculator fragment.
 */
public class CalculatorListAdapter extends BaseExpandableListAdapter {

	private ArrayList<Course> _courses;
	private Context _context;
	private SparseIntArray _coursesMap;
	private static final String FORECAST_TEXT="+ Course grade forecast";
	/**
	 * This constructor takes in a list of courses (without tutorials), and a context.
	 * @param courses
	 * @param context
	 */
	public CalculatorListAdapter(List<Course> courses,Context context){
		if (courses!=null) {
			_courses=new ArrayList<Course>(courses);
			//setup a helper map for courses
			_coursesMap=new SparseIntArray();
			int i=0;
			for (Course course : courses) {
				_coursesMap.put(course.get_courseID(), i);
				i++;
			}
		}
		_context=context;
	}

	@Override
	public Course getGroup(int groupPosition) {
		if (_courses!=null) {
			Course course=_courses.get(groupPosition);
			if (course.get_taskList()==null) {
				List<GenericTask> tasks=DatabaseManager.getInstance(_context).getCourseTasks(course.get_courseID());
				if (tasks!=null) {
					course.set_taskList(new ArrayList<GenericTask>(tasks));
				}else {
					course.set_taskList(new ArrayList<GenericTask>());
				}
			}
			
			return course;
		}
		return null;
	}

	@Override
	public int getGroupCount() {
		if (_courses!=null) {
			return _courses.size();
		}
		return 0;
	}
	
	/**
	 * This method is used to refresh the underlying course list.
	 * @param _courses
	 */
	public void set_courses(ArrayList<Course> _courses) {
		this._courses = _courses;
		_coursesMap=new SparseIntArray();
		int i=0;
		for (Course course : _courses) {
			_coursesMap.put(course.get_courseID(), i);
			i++;
		}
		//super.notifyDataSetChanged();
	}
	
	/**
	 * This is an overloaded version of the default <code>notifyDataSetChanged</code> method to just refresh the corresponding course.
	 * @param courseID
	 */
	public void notifyDataSetChanged(int courseID){
		int courseID1=_coursesMap.get(courseID);
		final Course c=_courses.get(courseID1);
			//DatabaseManager.getInstance(_context);
			//c.refreshAssignmentList();
		List<GenericTask> tasks=DatabaseManager.getInstance(_context).getCourseTasks(c.get_courseID());
		if (tasks!=null) {
			c.set_taskList(new ArrayList<GenericTask>(tasks));
		}else {
			c.set_taskList(new ArrayList<GenericTask>());
		}
			super.notifyDataSetChanged();
	}
	
	public ArrayList<Course> get_courses() {
		return _courses;
	}
	
	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		ViewHolder holder;
		TextView _txtPrefix;
		//first inflate our view and cache the ui elements into its viewholder object
		Course c=getGroup(groupPosition);
		
		if (convertView==null) {
			holder=new ViewHolder();
			convertView=LayoutInflater.from(_context).inflate(R.layout.course_list_item, null);
			holder._txtCourse=(TextView) convertView.findViewById(R.id.txt_list_course);
			holder._colorCourse=(TextView) convertView.findViewById(R.id.color_cell_course);
			_txtPrefix=(TextView) convertView.findViewById(R.id.txt_list_innerbox_prefix);
			_txtPrefix.setText(null);
			holder._txtCourseGrade=(TextView) convertView.findViewById(R.id.txt_list_innerbox_content);
			convertView.setTag(holder);
		}else {
			//always retrieve the viewholder from the tag
			holder=(ViewHolder) convertView.getTag();
		}
		holder._txtCourse.setText(c.toString());
		Drawable colorDrawable=holder._colorCourse.getBackground();
		UofTGrade grade=c.get_grade();
		if (grade==null || grade.get_marks()==0) {
			holder._txtCourseGrade.setText("0%");
		}else {
			holder._txtCourseGrade.setText(grade.toPercentageString());
		}
		
		if (colorDrawable instanceof LayerDrawable) {
			((LayerDrawable) colorDrawable).getDrawable(0).setColorFilter(c.get_color(), PorterDuff.Mode.SRC_ATOP);
		}
		return convertView;
	}

	@Override
	public boolean isEmpty() {
		if (_courses!=null) {
			return _courses.isEmpty();
		}
		return false;
	}

	/**
	 * A viewholder for parent row items.
	 */
	private static class ViewHolder{
		TextView _txtCourse;
		TextView _colorCourse;
		TextView _txtCourseGrade;
	}
	
	/**
	 * A viewholder for task row items.
	 */
	private static class TaskViewHolder{
		TextView _txtTaskName;
		TextView _txtGrade;
	}

	/**
	 * Return the corresponding assignment child from parent course. 
	 */
	@Override
	public GenericTask getChild(int groupPosition, int childPosition) {
		final Course c=_courses.get(groupPosition);
		final ArrayList<GenericTask> tasks=c.get_taskList();
		if (tasks!=null&&!tasks.isEmpty() && tasks.size()>childPosition) {
			GenericTask task=tasks.get(childPosition);
			return task;
		}else {
			return null;
		}
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		TaskViewHolder holder;
		if (convertView==null) {
			convertView=LayoutInflater.from(_context).inflate(R.layout.calculator_list_item, null);
			holder=new TaskViewHolder();
			holder._txtTaskName=(TextView) convertView.findViewById(R.id.txt_title);
			holder._txtGrade=(TextView) convertView.findViewById(R.id.txt_grade);
			convertView.setTag(holder);
		}else {
			holder=(TaskViewHolder) convertView.getTag();
		}
		GenericTask a=getChild(groupPosition, childPosition);
		//since we always append an extra item for adding new assignment,
		//so we might get a null child
		if (a!=null) {
			if (a instanceof Assignment) {
				holder._txtTaskName.setText(((Assignment)a).get_Title());
			}else {
				holder._txtTaskName.setText(((Exam)a).getTypeString());
			}
			
			
			holder._txtGrade.setVisibility(View.VISIBLE);
			holder._txtGrade.setText(a.get_grade().toString());
		}else {
			holder._txtTaskName.setText(FORECAST_TEXT);
			//we are here because this position is for the add button
			holder._txtTaskName.setPaintFlags(Paint.ANTI_ALIAS_FLAG);
			holder._txtGrade.setVisibility(View.INVISIBLE);
		}
		
		return convertView;
	}


	/**
	 * Get the children count, this will always return n+1 because we always append a dummy child at the end for the action button.
	 */
	@Override
	public int getChildrenCount(int groupPosition) {
		Course course=_courses.get(groupPosition);
		if (course == null)
			return 0;
		int count=0;
		List<GenericTask> courseTasks=course.get_taskList();
		if (courseTasks!=null) {
			count=courseTasks.size();
		}else {
			List<GenericTask> tasks=DatabaseManager.getInstance(_context).getCourseTasks(course.get_courseID());
			if (tasks!=null) {
				count=tasks.size();
				course.set_taskList(new ArrayList<GenericTask>(tasks));
			}else {
				course.set_taskList(new ArrayList<GenericTask>());
			}
		}
		if (count>0) {
			return count+1;
		}
		return 1;
	}
	
	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public boolean hasStableIds() {
		return false;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true;
	}
}
